/**
 * 
 */
package uk.ac.manchester.cs.graph.io;

import java.io.IOException;
import java.io.Reader;

import uk.ac.manchester.cs.graph.DirectedGraphImpl;
import uk.ac.manchester.cs.graph.Graph;
import uk.ac.manchester.cs.graph.GraphImpl;

/**
 * Very-very simplistic DOT parser with no aim to support all of the DOT syntax, no error recovery, etc.
 * 
 * Should be replaced by a more robust and complete implementation later.
 * 
 * @author Pavel Klinov
 *
 */
public class DOTReaderImpl<V,E> implements GraphReader<V, E> {

	private GraphNodeReader<V> m_nodeReader = null;
	
	@Override
	public Graph<V, E> read(Reader reader) throws IOException {

		DOTTokenStream stream = new DOTTokenStream(reader);
		String token = null;
		Graph<V,E> graph = null;
		
		while ((token = stream.nextToken()) != null) {
			
			if (token.startsWith("graph")) {
				
				graph = new GraphImpl<V,E>();
				
			} else if (token.startsWith("digraph")) {
				
				graph = new DirectedGraphImpl<V,E>();
				
			} else if (!token.startsWith("\"")) {
				//Bad token, we should raise an error here but we don't care
				continue;
				
			} else {
				
				String[] parts = token.split("->");
				
				if (parts.length == 1) {
					//Node
					V node = m_nodeReader.read(stripQuotes(parts[0]));
					
					graph.addVertex(node);
					
				} else {
					//Edge
					V start = m_nodeReader.read(stripQuotes(parts[0]));
					V end = m_nodeReader.read(stripQuotes(parts[1]));
					
					graph.addEdge(null, start, end);
				}
			}
		}
		
		return graph;
	}

	
	private String stripQuotes(String token) {

		token = token.trim();
		
		if (token.startsWith("\"") && token.endsWith("\"")) {
			
			token = token.substring(1, token.length() - 1);
		}
		
		return token;
	}

	@Override
	public void setNodeReader(GraphNodeReader<V> nodeReader) {

		m_nodeReader = nodeReader;
	}
}
